package com.qdlc.p2p.dal.dto;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.google.gson.annotations.Expose;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.util.BigDecimalUtil;

/**
 * 借款标
 *
 * @author liya
 * @version 1.1.0.0
 */
@Entity
@Table(name = Global.DB_PREFIX + "borrow")
public class Borrow implements Serializable {

    private static final long serialVersionUID = -3713767336260018418L;

    /** 主键 */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Expose
    private long id;

    /** 唯一标识 */
    @Expose
    private String uuid;

    /** 借款人 */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    @Expose
    private User user;

    /** 借款标题 */
    @Expose
    private String name;

    /** 借款标信息详情 */
    private String content;

    /** 标种 */
    @Expose
    private int type;

    /**
     * 标状态 -1用户撤回;0等待初审;1初审通过;2初审未通过;3复审通过;4/49复审未通过;5/59管理员撤回;6还款中;69 放款出错待补单;7部分还款;8还款成功；
     * 环讯新增状态  9：登记成功（对应环讯接口文档中MG02500F） 11 募集中（只有为这个状态才能初审 （对应环讯接口文档中MG02501F）），
     * -2：撤回处理中（（对应环讯接口文档中MG02503F））  5: 管理员撤回（对应环讯接口文档中MG02505F）
     */
    @Expose
    private int status;

    /** 期数 */
    @Expose
    private int period;

    /** 借款总额 */
    @Expose
    private double account;

    /** 实还总金额(已借) */
    @Expose
    private double accountYes;

    /** 完成比例 */
    @Expose
    private double scales;

    /** 年利率 */
    @Expose
    private double apr;

    /** 还款方式 1按月分期还款; 2一次性还款;3每月还息到期还本 */
    @Expose
    private int style;

    /** 借款用途 */
    @Expose
    private String borrowUse;

    /** 标时间类型 0月标 1天标 */
    @Expose
    private int borrowTimeType;

    /** 借款期限 */
    @Expose
    private int timeLimit;

    /** 定向密码 */
    @Expose
    private String pwd;

    /** 定时时间 */
    @Expose
    private Date fixedTime;

    /** 是否推荐标 0普通标; 1推荐标 */
    @Expose
    private boolean isRecommend;

    /** 最低投标金额 */
    @Expose
    private double lowestAccount;

    /** 最多投标金额 */
    @Expose
    private double mostAccount;

    /** 单笔最低限额 */
    @Expose
    private double lowestSingleLimit;

    /** 单笔最高限额 */
    @Expose
    private double mostSingleLimit;

    /** 应还本金 */
    @Expose
    private double repaymentAccount;

    /** 实还本金 */
    @Expose
    private double repaymentYesAccount;

    /** 实还利息 */
    @Expose
    private double repaymentYesInterest;

    /** 投标完成笔数 */
    @Expose
    private int tenderTimes;

    /** 添加时间 */
    @Expose
    private Date addTime;

    /** 复审时间 */
    @Expose
    private Date reviewTime;

    /** ip */
    @Expose
    private String addIp;

    /** 截标前account值 */
    @Expose
    private double oldAccount;

    /** 投标奖励  0没有奖励;1比例奖励;2分摊奖励 */
    @Expose
    private int award;

    /** 按投标金额比例(0.1-6) */
    @Expose
    private double partAccount;

    /** 分摊奖励金额 */
    @Expose
    private double funds;

    /** 标的号 */
    @Expose
    private String bidNo;

    /** 登记时间 */
    @Expose
    private Date registerTime;

    /** 资产包性质 */
    @Expose
    private String portfolioProp;

    /** 合同号 */
    @Expose
    private String dealNo;

    /**
     * 担保公司
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "vouch_id")
    private User vouchFirm;

    /** 借款手续费率 */
    @Expose
    private double borrowManageRate;

    /** 平台实际收取借款管理费 */
    @Expose
    private double manageFee;

    /** 担保费率 */
    @Expose
    private double guaranteeRate;

    /** 登记担保方时候的订单号 */
    @Expose
    private String guaranteeNo;

    /** 开标时间 */
    @Column(name = "put_start_time")
    @Expose
    private Date putStartTime;

    /** 1：普通标 0：新手标 */
    @Column(name = "category")
    @Expose
    private Integer category;

    /** 投资次数 */
    @Column(name = "invest_count")
    @Expose
    private Integer investCount;

    /**
     * 设置是否是投标 用户 borrowHelper中做判断，不需要关联数据库
     */
    @Transient
    private int isTender;

    /**
     * 获取主键
     *
     * @return 主键
     */
    public long getId() {
        return id;
    }

    /**
     * 设置主键
     *
     * @param id 要设置的主键
     */
    public void setId(long id) {
        this.id = id;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    public User getUser() {
        return user;
    }

    /**
     * 设置用户信息
     *
     * @param user 要设置的用户信息
     */
    public void setUser(User user) {
        this.user = user;
    }

    /**
     * 获取借款标题
     *
     * @return 借款标题
     */
    public String getName() {
        return name;
    }

    /**
     * 设置借款标题
     *
     * @param name 要设置的借款标题
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取借款标信息内容
     *
     * @return 借款标信息内容
     */
    public String getContent() {
        return content;
    }

    /**
     * 设置借款标信息内容
     *
     * @param content 要设置的借款标信息内容
     */
    public void setContent(String content) {
        this.content = content;
    }

    /**
     * 获取标种
     *
     * @return 标种
     */
    public int getType() {
        return type;
    }

    /**
     * 设置标种
     *
     * @param type 要设置的标种
     */
    public void setType(int type) {
        this.type = type;
    }

    /**
     * 标状态
     *
     * @return 标状态
     */
    public int getStatus() {
        return status;
    }

    /**
     * 设置标状态
     *
     * @param status 要设置的标状态
     */
    public void setStatus(int status) {
        this.status = status;
    }

    /**
     * 获取期数
     *
     * @return 期数
     */
    public int getPeriod() {
        return period;
    }

    /**
     * 设置期数
     *
     * @param period 要设置的期数
     */
    public void setPeriod(int period) {
        this.period = period;
    }

    /**
     * 获取借款总额
     *
     * @return 借款总额
     */
    public double getAccount() {
        return account;
    }

    /**
     * 设置借款总额
     *
     * @param account 要设置的借款总额
     */
    public void setAccount(double account) {
        this.account = account;
    }

    /**
     * 获取年利率
     *
     * @return 年利率
     */
    public double getApr() {
        return apr;
    }

    /**
     * 设置年利率
     *
     * @param apr 要设置的年利率
     */
    public void setApr(double apr) {
        this.apr = apr;
    }

    /**
     * 获取借款用途
     *
     * @return 借款用途
     */
    public String getBorrowUse() {
        return borrowUse;
    }

    /**
     * 设置借款用途
     *
     * @param borrowUse 要设置的借款用途
     */
    public void setBorrowUse(String borrowUse) {
        this.borrowUse = borrowUse;
    }

    /**
     * 获取标类 0月标 1天标
     *
     * @return 标类 0月标 1天标
     */
    public int getBorrowTimeType() {
        return borrowTimeType;
    }

    /**
     * 设置标类 0月标 1天标
     *
     * @param borrowTimeType 要设置的标类 0月标 1天标
     */
    public void setBorrowTimeType(int borrowTimeType) {
        this.borrowTimeType = borrowTimeType;
    }

    /**
     * 获取借款期限
     *
     * @return 借款期限
     */
    public int getTimeLimit() {
        return timeLimit;
    }

    /**
     * 设置借款期限
     *
     * @param timeLimit 要设置的借款期限
     */
    public void setTimeLimit(int timeLimit) {
        this.timeLimit = timeLimit;
    }

    /**
     * 获取定向密码
     *
     * @return 定向密码
     */
    public String getPwd() {
        return pwd;
    }

    /**
     * 设置定向密码
     *
     * @param pwd 要设置的定向密码
     */
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    /**
     * 获取定时时间
     *
     * @return 定时时间
     */
    public Date getFixedTime() {
        return fixedTime;
    }

    /**
     * 设置定时时间
     *
     * @param fixedTime 要设置的定时时间
     */
    public void setFixedTime(Date fixedTime) {
        this.fixedTime = fixedTime;
    }


    /**
     * 获取是否推荐标 0普通标; 1推荐标
     *
     * @return 是否推荐标 0普通标; 1推荐标
     */
    public boolean isRecommend() {
        return isRecommend;
    }

    /**
     * 设置是否推荐标 0普通标; 1推荐标
     *
     * @param isRecommend 要设置的是否推荐标 0普通标; 1推荐标
     */
    public void setRecommend(boolean isRecommend) {
        this.isRecommend = isRecommend;
    }

    /**
     * 获取最低投标金额
     *
     * @return 最低投标金额
     */
    public double getLowestAccount() {
        return lowestAccount;
    }

    /**
     * 设置最低投标金额
     *
     * @param lowestAccount 要设置的最低投标金额
     */
    public void setLowestAccount(double lowestAccount) {
        this.lowestAccount = lowestAccount;
    }

    /**
     * 获取最多投标金额
     *
     * @return 最多投标金额
     */
    public double getMostAccount() {
        return mostAccount;
    }

    /**
     * 设置最多投标金额
     *
     * @param mostAccount 要设置的最多投标金额
     */
    public void setMostAccount(double mostAccount) {
        this.mostAccount = mostAccount;
    }

    /**
     * 获取单笔最低限额
     *
     * @return 单笔最低限额
     */
    public double getLowestSingleLimit() {
        return lowestSingleLimit;
    }

    /**
     * 设置单笔最低限额
     *
     * @param lowestSingleLimit 要设置的单笔最低限额
     */
    public void setLowestSingleLimit(double lowestSingleLimit) {
        this.lowestSingleLimit = lowestSingleLimit;
    }

    /**
     * 获取单笔最高限额
     *
     * @return 单笔最高限额
     */
    public double getMostSingleLimit() {
        return mostSingleLimit;
    }

    /**
     * 设置单笔最高限额
     *
     * @param mostSingleLimit 要设置的单笔最高限额
     */
    public void setMostSingleLimit(double mostSingleLimit) {
        this.mostSingleLimit = mostSingleLimit;
    }

    /**
     * 获取还款方式
     *
     * @return 还款方式
     */
    public int getStyle() {
        return style;
    }

    /**
     * 设置还款方式
     *
     * @param style 要设置的还款方式
     */
    public void setStyle(int style) {
        this.style = style;
    }

    /**
     * 获取实还总金额
     *
     * @return 实还总金额
     */
    public double getAccountYes() {
        return accountYes;
    }

    /**
     * 设置实还总金额
     *
     * @param accountYes 要设置的实还总金额
     */
    public void setAccountYes(double accountYes) {
        this.accountYes = accountYes;
    }

    /**
     * 获取应还本金
     *
     * @return 应还本金
     */
    public double getRepaymentAccount() {
        return repaymentAccount;
    }

    /**
     * 设置应还本金
     *
     * @param repaymentAccount 要设置的应还本金
     */
    public void setRepaymentAccount(double repaymentAccount) {
        this.repaymentAccount = repaymentAccount;
    }

    /**
     * 获取实还本金
     *
     * @return 实还本金
     */
    public double getRepaymentYesAccount() {
        return repaymentYesAccount;
    }

    /**
     * 设置实还本金
     *
     * @param repaymentYesAccount 要设置的实还本金
     */
    public void setRepaymentYesAccount(double repaymentYesAccount) {
        this.repaymentYesAccount = repaymentYesAccount;
    }

    /**
     * 获取实还利息
     *
     * @return 实还利息
     */
    public double getRepaymentYesInterest() {
        return repaymentYesInterest;
    }

    /**
     * 设置实还利息
     *
     * @param repaymentYesInterest 要设置的实还利息
     */
    public void setRepaymentYesInterest(double repaymentYesInterest) {
        this.repaymentYesInterest = repaymentYesInterest;
    }

    public Date getAddTime() {
        return addTime;
    }

    public void setAddTime(Date addTime) {
        this.addTime = addTime;
    }

    /**
     * 获取ip
     *
     * @return ip
     */
    public String getAddIp() {
        return addIp;
    }

    /**
     * 设置ip
     *
     * @param addIp 要设置的ip
     */
    public void setAddIp(String addIp) {
        this.addIp = addIp;
    }

    /**
     * 获取完成比例
     *
     * @return 完成比例
     */
    public double getScales() {
        return scales;
    }

    /**
     * 设置完成比例
     *
     * @param scales 要设置的完成比例
     */
    public void setScales(double scales) {
        this.scales = scales;
    }

    public int getTenderTimes() {
        return tenderTimes;
    }

    public void setTenderTimes(int tenderTimes) {
        this.tenderTimes = tenderTimes;
    }

    public double getOldAccount() {
        return oldAccount;
    }

    public void setOldAccount(double oldAccount) {
        this.oldAccount = oldAccount;
    }

    public int getAward() {
        return award;
    }

    public void setAward(int award) {
        this.award = award;
    }

    public double getPartAccount() {
        return partAccount;
    }

    public void setPartAccount(double partAccount) {
        this.partAccount = partAccount;
    }

    public double getFunds() {
        return funds;
    }

    public void setFunds(double funds) {
        this.funds = funds;
    }

    public String getBidNo() {
        return bidNo;
    }

    public void setBidNo(String bidNo) {
        this.bidNo = bidNo;
    }

    public String getPortfolioProp() {
        return portfolioProp;
    }

    public void setPortfolioProp(String portfolioProp) {
        this.portfolioProp = portfolioProp;
    }

    public User getVouchFirm() {
        return vouchFirm;
    }

    public void setVouchFirm(User vouchFirm) {
        this.vouchFirm = vouchFirm;
    }

    public String getDealNo() {
        return dealNo;
    }

    public void setDealNo(String dealNo) {
        this.dealNo = dealNo;
    }

    public Date getRegisterTime() {
        return registerTime;
    }

    public void setRegisterTime(Date registerTime) {
        this.registerTime = registerTime;
    }


    public double getBorrowManageRate() {
        return borrowManageRate;
    }

    public void setBorrowManageRate(double borrowManageRate) {
        this.borrowManageRate = borrowManageRate;
    }

    public double getGuaranteeRate() {
        return guaranteeRate;
    }

    public void setGuaranteeRate(double guaranteeRate) {
        this.guaranteeRate = guaranteeRate;
    }

    public String getGuaranteeNo() {
        return guaranteeNo;
    }

    public void setGuaranteeNo(String guaranteeNo) {
        this.guaranteeNo = guaranteeNo;
    }

    public Date getReviewTime() {
        return reviewTime;
    }

    public void setReviewTime(Date reviewTime) {
        this.reviewTime = reviewTime;
    }

    public void setManageFee(double manageFee) {
        this.manageFee = manageFee;
    }

    /**
     * 计算担保收益金额
     *
     * @return
     */
    public double getGuaranteeFee() {
        double fee = 0;
        if (this.borrowTimeType == 0) {// 如果是月标，则算月收益再乘以月数
            fee = this.guaranteeRate * this.timeLimit * this.account / 12 / 100;
        } else {// 如果是天标，则算天收益再乘以天数
            //一年以365天计算
            fee = this.guaranteeRate * this.timeLimit * this.account / 365 / 100;
        }
        return fee;
    }

    /**
     * 获取平台可得的借款管理费：
     *
     * @return
     */
    public double getManageFee() {
        /**
         * 费率计算规则：（登记的费率/100*借款金额-分给担保方的金额）/借款金额 
         */
        double guaranteeFee = this.getGuaranteeFee();
        manageFee = BigDecimalUtil.sub(BigDecimalUtil.mul(this.account, this.borrowManageRate) / 100, guaranteeFee);
        return manageFee;
    }

    @Column(name = "put_start_time")
    public Date getPutStartTime() {
        return putStartTime;
    }

    public void setPutStartTime(Date putStartTime) {
        this.putStartTime = putStartTime;
    }

    @Column(name = "category")
    public Integer getCategory() {
        return category;
    }

    public void setCategory(Integer category) {
        this.category = category;
    }

    @Column(name = "invest_count")
    public Integer getInvestCount() {
        return investCount;
    }


    public void setInvestCount(Integer investCount) {
        this.investCount = investCount;
    }

    /**
     * 获取
     *
     * @return
     */
    public int getIsTender() {
        return isTender;
    }

    /**
     * 设置
     *
     * @param
     */
    public void setIsTender(int isTender) {
        this.isTender = isTender;
    }

    /**
     * 获取平台可得的管理费率：
     *
     * @return
     */
    public double getManageFeeRate() {
        return BigDecimalUtil.div(this.getManageFee(), this.account);
    }

    public double getGuarantorMoney() {
        // 环迅最高支持年利50%，担保金额考虑逾期，则担保金额最高为本金+本金*年利50%*借款期限/12/100
        double guarantorMoney = 0;
        if (this.getBorrowTimeType() == 0) {// 如果是月标，则算月收益再乘以月数
            guarantorMoney = this.getAccount() + this.getAccount() * 0.5 * this.getTimeLimit() / 12;
        } else {// 如果是天标，则算天收益再乘以天数
            //一年以365天计算
            guarantorMoney = this.getAccount() + this.getAccount() * 0.5 * this.getTimeLimit() / 365;
        }
        return guarantorMoney;
    }
}
